package ibm.cognos.imt; /**
Licensed Materials - Property of IBM

IBM Cognos Products: DOCS

(C) Copyright IBM Corp. 2005, 2008

US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with
IBM Corp.
*/
/**
 * ReportRunner2.java
 *
 * Copyright (C) 2008 Cognos ULC, an IBM Company. All rights reserved.
 * Cognos (R) is a trademark of Cognos ULC, (formerly Cognos Incorporated).
 *
 */

import com.cognos.developer.schemas.bibus._3.*;
import org.apache.axis.AxisFault;
import org.apache.axis.client.Stub;

import javax.xml.rpc.ServiceException;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * Run a report from the samples deployment archive, and save its output
 * as HTML.
 *
 * Note that this application does no error handling; errors will cause
 * ugly exception stack traces to appear on the console, and the
 * application will exit ungracefully.
 */
public class ReportRunner2
{

	/**
	 * This function will prepare the biBusHeader.
	 *
	 * @param repService An initialized report service object.
	 * @param user       Log in as this User ID in the specified namespace.
	 * @param pass       Password for user in the specified namespace.
	 * @param name       The security namespace to log on to.
	 */
//    static String serverHost = "9.110.94.115";

	static void setUpHeader(
		ReportService_PortType repService,
		String user,
		String pass,
		String name)
	{
		// Scrub the header to remove the conversation context.
		BiBusHeader bibus =
			BIBusHeaderHelper.getHeaderObject(((Stub)repService).getResponseHeader("", "biBusHeader"));
				
		if (bibus != null)
		{
			if (bibus.getTracking() != null)
			{
				if (bibus.getTracking().getConversationContext() != null)
				{
					bibus.getTracking().setConversationContext(null);
				}
			}

			return;
		}

		// Set up a new biBusHeader for the "logon" action.
		bibus = new BiBusHeader();
		bibus.setCAM(new CAM());
		bibus.getCAM().setAction("logonAs");
		bibus.setHdrSession(new HdrSession());

		FormFieldVar ffs[] = new FormFieldVar[3];

		ffs[0] = new FormFieldVar();
		ffs[0].setName("CAMUsername");
		ffs[0].setValue(user);
		ffs[0].setFormat(FormatEnum.not_encrypted);

		ffs[1] = new FormFieldVar();
		ffs[1].setName("CAMPassword");
		ffs[1].setValue(pass);
		ffs[1].setFormat(FormatEnum.not_encrypted);

		ffs[2] = new FormFieldVar();
		ffs[2].setName("CAMNamespace");
		ffs[2].setValue(name);
		ffs[2].setFormat(FormatEnum.not_encrypted);

		bibus.getHdrSession().setFormFieldVars(ffs);

		((Stub)repService).setHeader("http://developer.cognos.com/schemas/bibus/3/", "biBusHeader", bibus);
	}



	static void showUsage()
	{
		String usage = "";
		usage += "Run a report and save the output as HTML.";
		usage += "usage:";
		usage += "-host hostNameHost name of an IBM Cognos server.";
		usage += " Default: localhost";
		usage += "-port portNumberPort number of the server.";
		usage += " Default: 9300";
		usage
			+= "-report searchPathSearch path to a report.";
		usage += " Default: "
			+ "/content/folder[@name='Samples']/folder[@name='Models']/package[@name='GO Data Warehouse (query)']"
			+ "/folder[@name='SDK Report Samples']"
			+ "/report[@name='Product Introduction List']";
		usage
			+= "-output outputPathFile name for the output HTML document.";
		usage += " Default: ReportRunner2.html";
		usage += "-user userNameUser to log on as. "
			+ "Must exist in 'userNamespace'.";
		usage += " Default: none";
		usage += "-password userPasswordPassword for 'userName' ";
		usage += "in 'userNamespace'.";
		usage += " Default: none";
		usage
			+= "-namespace userNamespaceSecurity namespace to log on to.";
		usage += " Default: none";

		System.out.println(usage);
	}

	/**
	 * Replace all occurrences of "pattern" in "str" with "replace".
	 *
	 * @param str      The source string.
	 * @param pattern  The pattern to search for.
	 * @param replace  The replacement for pattern.
	 *
	 * @return         Identical to the original string with all instances
	 *                 of "pattern" replaced by "replace"
	 */
	public static String replaceSubstring(
		String str,
		String pattern,
		String replace)
	{
		int strLen = str.length();
		int patternLen = pattern.length();
		int start = 0, end = 0;
		StringBuffer result = new StringBuffer(strLen);
		char[] chars = new char[strLen];

		while ((end = str.indexOf(pattern, start)) >= 0)
		{
			str.getChars(start, end, chars, 0);
			result.append(chars, 0, end - start).append(replace);
			start = end + patternLen;
		}

		str.getChars(start, strLen, chars, 0);
		result.append(chars, 0, strLen - start);

		return result.toString();
	}

    public static String[] generateHtml(String spec){
        Option runOptions[] = new Option[5];

        RunOptionBoolean saveOutput = new RunOptionBoolean();
        saveOutput.setName(RunOptionEnum.saveOutput);
        saveOutput.setValue(false);
        runOptions[0] = saveOutput;

        // TODO: Output format should be specified on the command-line
        RunOptionStringArray outputFormat = new RunOptionStringArray();
        outputFormat.setName(RunOptionEnum.outputFormat);
        outputFormat.setValue(new String[] { "HTML" });
        runOptions[1] = outputFormat;

        RunOptionOutputEncapsulation outputEncapsulation =
                new RunOptionOutputEncapsulation();
        outputEncapsulation.setName(RunOptionEnum.outputEncapsulation);
        outputEncapsulation.setValue(OutputEncapsulationEnum.none);
        runOptions[2] = outputEncapsulation;

        AsynchOptionInt primaryWait = new AsynchOptionInt();
        primaryWait.setName(AsynchOptionEnum.primaryWaitThreshold);
        primaryWait.setValue(0);
        runOptions[3] = primaryWait;

        AsynchOptionInt secondaryWait = new AsynchOptionInt();
        secondaryWait.setName(AsynchOptionEnum.secondaryWaitThreshold);
        secondaryWait.setValue(0);
        runOptions[4] = secondaryWait;

        return generateReport(spec, runOptions);
    }

    public static String[] generateXml(String spec){
        Option runOptions[] = new Option[5];

        RunOptionBoolean saveOutput = new RunOptionBoolean();
        saveOutput.setName(RunOptionEnum.saveOutput);
        saveOutput.setValue(false);
        runOptions[0] = saveOutput;

        // TODO: Output format should be specified on the command-line
        RunOptionStringArray outputFormat = new RunOptionStringArray();
        outputFormat.setName(RunOptionEnum.outputFormat);
        outputFormat.setValue(new String[] { "XML" });
        runOptions[1] = outputFormat;

        RunOptionOutputEncapsulation outputEncapsulation =
                new RunOptionOutputEncapsulation();
        outputEncapsulation.setName(RunOptionEnum.outputEncapsulation);
        outputEncapsulation.setValue(OutputEncapsulationEnum.none);
        runOptions[2] = outputEncapsulation;

        AsynchOptionInt primaryWait = new AsynchOptionInt();
        primaryWait.setName(AsynchOptionEnum.primaryWaitThreshold);
        primaryWait.setValue(0);
        runOptions[3] = primaryWait;

        AsynchOptionInt secondaryWait = new AsynchOptionInt();
        secondaryWait.setName(AsynchOptionEnum.secondaryWaitThreshold);
        secondaryWait.setValue(0);
        runOptions[4] = secondaryWait;

        return generateReport( spec, runOptions);
    }

    public static String generateImbedReport(String spec) {
        Option runOptions[] = new Option[5];

        RunOptionBoolean saveOutput = new RunOptionBoolean();
        saveOutput.setName(RunOptionEnum.saveOutput);
        saveOutput.setValue(false);
        runOptions[0] = saveOutput;

        // TODO: Output format should be specified on the command-line
        RunOptionStringArray outputFormat = new RunOptionStringArray();
        outputFormat.setName(RunOptionEnum.outputFormat);
        outputFormat.setValue(new String[] { "HTML" });
        runOptions[1] = outputFormat;

        RunOptionOutputEncapsulation outputEncapsulation =
                new RunOptionOutputEncapsulation();
        outputEncapsulation.setName(RunOptionEnum.outputEncapsulation);
        outputEncapsulation.setValue(OutputEncapsulationEnum.none);
        runOptions[2] = outputEncapsulation;

        AsynchOptionInt primaryWait = new AsynchOptionInt();
        primaryWait.setName(AsynchOptionEnum.primaryWaitThreshold);
        primaryWait.setValue(0);
        runOptions[3] = primaryWait;

        AsynchOptionInt secondaryWait = new AsynchOptionInt();
        secondaryWait.setName(AsynchOptionEnum.secondaryWaitThreshold);
        secondaryWait.setValue(0);
        runOptions[4] = secondaryWait;
//        String html = generateReport(serverUrl, gatewayPort, spec, runOptions)[0];
        String html = generateReport(spec, runOptions)[0];
        ReportHtmlUtil util = new ReportHtmlUtil(html);
        String result = util.transform();
//        System.out.println(result);
        return result;

    }

//    public static void main(String[] args) throws IOException {
//        String spec = FileUtils.readFileToString(new File("c:\\saved_spec.xml"));
//        System.out.println(generateHtml(spec));
//    }

    public static String[] generateReport(String spec, Option[] runOptions) {

        // Change this search path if you want to run a different report.
//		String reportPath =
//			"/content/folder[@name='Samples']/folder[@name='Models']/package[@name='GO Data Warehouse (query)']"
//				+ "/folder[@name='SDK Report Samples']"
//				+ "/report[@name='Product Introduction List']";

//		String reportPath =
//			"/content/folder[@name='Samples']/folder[@name='Models']/package[@name='GO Sales (analysis)']" +
//			"/folder[@name='Report Studio Report Samples']/report[@name='2011 Quarterly Sales Forecast']";

//		String reportPath = "/content/package[@name='Sample_U_Basic']/report[@name='Essbase']";

        // Output filename
//        String outputPath = "ReportRunner2.html";

        // Specify a user to log in as.
        String userName = "";
        String userPassword = "";
        String userNamespace = "";

        System.out.println("Creating connection to " + BiServerConfig.dispatcherURI() + "...");
        ReportService_ServiceLocator reportServiceLocator =  new ReportService_ServiceLocator();

        ReportService_PortType repService = null;

        try
        {
            repService = reportServiceLocator.getreportService(new URL(BiServerConfig.dispatcherURI()));
        }
        catch (ServiceException ex)
        {
            System.out.println("Caught a ServiceException: " + ex.getMessage());
            ex.printStackTrace();
            System.exit(-1);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

        // Set up the biBusHeader for a logon.
        if ((userName.length() > 0)
                && (userPassword.length() > 0)
                && (userNamespace.length() > 0))
        {
            System.out.println(
                    "Logging on as "
                            + userName
                            + " in the "
                            + userNamespace
                            + " namespace.");
            setUpHeader(repService, userName, userPassword, userNamespace);
        }

        // Set up the report parameters.
        ParameterValue parameters[] = new ParameterValue[] {};

//        Option runOptions[] = new Option[5];
//
//        RunOptionBoolean saveOutput = new RunOptionBoolean();
//        saveOutput.setName(RunOptionEnum.saveOutput);
//        saveOutput.setValue(false);
//        runOptions[0] = saveOutput;
//
//        // TODO: Output format should be specified on the command-line
//        RunOptionStringArray outputFormat = new RunOptionStringArray();
//        outputFormat.setName(RunOptionEnum.outputFormat);
//        outputFormat.setValue(new String[] { "HTML" });
//        runOptions[1] = outputFormat;
//
//        RunOptionOutputEncapsulation outputEncapsulation =
//                new RunOptionOutputEncapsulation();
//        outputEncapsulation.setName(RunOptionEnum.outputEncapsulation);
//        outputEncapsulation.setValue(OutputEncapsulationEnum.none);
//        runOptions[2] = outputEncapsulation;
//
//        AsynchOptionInt primaryWait = new AsynchOptionInt();
//        primaryWait.setName(AsynchOptionEnum.primaryWaitThreshold);
//        primaryWait.setValue(0);
//        runOptions[3] = primaryWait;
//
//        AsynchOptionInt secondaryWait = new AsynchOptionInt();
//        secondaryWait.setName(AsynchOptionEnum.secondaryWaitThreshold);
//        secondaryWait.setValue(0);
//        runOptions[4] = secondaryWait;

        String[] data= null;

        // Now, run the report.
        try
        {
            System.out.println("Running the report...");

//			AsynchReply res =
//                repService.run(new SearchPathSingleObject(reportPath), parameters, runOptions);

            ReportServiceSpecification metadataSpec = new ReportServiceReportSpecification();
            metadataSpec.setValue(new Specification(spec));

            AsynchReply res = repService.runSpecification(metadataSpec, parameters, runOptions);

            System.out.println(res+"... done.");

            // The report is finished, let's fetch the results and save them to
            // a file.
            if (res.getStatus() == AsynchReplyStatusEnum.complete)

            {
                AsynchDetailReportOutput reportOutput = null;

                for (int i = 0; i < res.getDetails().length; i++)
                {
                    if (res.getDetails()[i]
                            instanceof AsynchDetailReportOutput)
                    {
                        reportOutput =
                                (AsynchDetailReportOutput)res.getDetails()[i];
                        break;
                    }
                }

                String[] pages = reportOutput.getOutputPages();
                data = new String[pages.length];
                for (int i = 0; i < data.length; i++) {
                    data[i] = replaceSubstring(pages[i], "../", BiServerConfig.gatewayResourceURI());

//                    data[i] = replaceSubstring(data[i], "src=\"?", "src=\"http://" + serverHost + ":"+gatewayPort+"/ibmcognos/cgi-bin/cognos.cgi?");
                    data[i] = replaceSubstring(data[i], "src=\"?", "src=\""+BiServerConfig.gatewayCgi()+"?");
                }

//                System.out.println(
//                        "Writing report output to " + outputPath + "...");
//                FileOutputStream fs = new FileOutputStream(outputPath);
//
//                // URIs in the output are relative on the server; we need to
//                // make them absolute so they reference the server properly.
//				String uriFix =
//					"http://" + serverHost + ":" + serverPort + "/ibmcognos/";
//
//                String uriFix =
//                        "http://" + serverHost + "/ibmcognos/";
//
//                for (int idx = 0; idx < data.length; idx++)
//                {
//                    String fixed_hunk =
//                            replaceSubstring(data[idx], "../", uriFix);
////                    fs.write(fixed_hunk.getBytes());
//                }
//
//                fs.close();
//                System.out.println("... done.");
            }
        }
        catch (AxisFault ex)
        {
            String ex_str = CognosBIException.convertToString(ex);
            System.out.println("SOAP exception!");
            System.out.println(ex_str);
            ex.printStackTrace();
        }
        catch (Exception ex)
        {
            System.out.println("Unhandled exception!");
            System.out.println("Message: " + ex.getMessage());
            System.out.println("Stack trace:");
            ex.printStackTrace();
        }
        return data;
    }

    //Todo: should support run existing report
//    public static String[] runExistingReport() {
//
//    }

    //todo: should support save new report to content store

	/*
	 * The main entry point for the application.
	 */
//	public static void main(String[] args)
//	{
//		// Change this URL if your server is in another location or a
//		// different port.
////        String serverHost = "9.119.129.23";
////		String serverHost = "9.119.141.62";
//        String serverHost = "9.110.94.115";
//		String serverPort = "9300";
//
//		// Change this search path if you want to run a different report.
////		String reportPath =
////			"/content/folder[@name='Samples']/folder[@name='Models']/package[@name='GO Data Warehouse (query)']"
////				+ "/folder[@name='SDK Report Samples']"
////				+ "/report[@name='Product Introduction List']";
//
////		String reportPath =
////			"/content/folder[@name='Samples']/folder[@name='Models']/package[@name='GO Sales (analysis)']" +
////			"/folder[@name='Report Studio Report Samples']/report[@name='2011 Quarterly Sales Forecast']";
//
////		String reportPath = "/content/package[@name='Sample_U_Basic']/report[@name='Essbase']";
//
//		// Output filename
//		String outputPath = "ReportRunner2.html";
//
//		// Specify a user to log in as.
//		String userName = "";
//		String userPassword = "";
//		String userNamespace = "";
//
//		// Parse the command-line arguments.
//		for (int idx = 0; idx < args.length; idx++)
//		{
//			if (args[idx].compareTo("-host") == 0)
//			{
//				serverHost = args[idx + 1];
//			}
//			else if (args[idx].compareTo("-port") == 0)
//			{
//				serverPort = args[idx + 1];
//			}
////			else if (args[idx].compareTo("-report") == 0)
////			{
////				reportPath = args[idx + 1];
////			}
//			else if (args[idx].compareTo("-output") == 0)
//			{
//				outputPath = args[idx + 1];
//			}
//			else if (args[idx].compareTo("-user") == 0)
//			{
//				userName = args[idx + 1];
//			}
//			else if (args[idx].compareTo("-password") == 0)
//			{
//				userPassword = args[idx + 1];
//			}
//			else if (args[idx].compareTo("-namespace") == 0)
//			{
//				userNamespace = args[idx + 1];
//			}
//			else
//			{
//				System.out.println("Unknown argument: " + args[idx]);
//				showUsage();
//				System.exit(0);
//			}
//			idx++;
//		}
//
//		// Create a connection to a report server.
//		String Cognos_URL =
//			"http://"
//				+ serverHost
//				+ ":"
//				+ serverPort
//				+ "/p2pd/servlet/dispatch";
//
//		System.out.println(
//			"Creating connection to "
//				+ serverHost
//				+ ":"
//				+ serverPort
//				+ "...");
//		System.out.println("Server URL: " + Cognos_URL);
//		ReportService_ServiceLocator reportServiceLocator =
//			new ReportService_ServiceLocator();
//
//		ReportService_PortType repService = null;
//
//		try
//		{
//			repService = reportServiceLocator.getreportService(new URL(Cognos_URL));
//		}
//		catch (MalformedURLException ex)
//		{
//			System.out.println(
//				"Caught a MalformedURLException:" + ex.getMessage());
//			System.out.println("Server URL was: " + Cognos_URL);
//			System.exit(-1);
//		}
//		catch (ServiceException ex)
//		{
//			System.out.println("Caught a ServiceException: " + ex.getMessage());
//			ex.printStackTrace();
//			System.exit(-1);
//		}
//
//		System.out.println("... done.");
//
//		// Set up the biBusHeader for a logon.
//		if ((userName.length() > 0)
//			&& (userPassword.length() > 0)
//			&& (userNamespace.length() > 0))
//		{
//			System.out.println(
//				"Logging on as "
//					+ userName
//					+ " in the "
//					+ userNamespace
//					+ " namespace.");
//			setUpHeader(repService, userName, userPassword, userNamespace);
//		}
//
//		// Set up the report parameters.
//		ParameterValue parameters[] = new ParameterValue[] {};
//
//		Option runOptions[] = new Option[5];
//
//		RunOptionBoolean saveOutput = new RunOptionBoolean();
//		saveOutput.setName(RunOptionEnum.saveOutput);
//		saveOutput.setValue(false);
//		runOptions[0] = saveOutput;
//
//		// TODO: Output format should be specified on the command-line
//		RunOptionStringArray outputFormat = new RunOptionStringArray();
//		outputFormat.setName(RunOptionEnum.outputFormat);
//		outputFormat.setValue(new String[] { "HTML" });
//		runOptions[1] = outputFormat;
//
//		RunOptionOutputEncapsulation outputEncapsulation =
//			new RunOptionOutputEncapsulation();
//		outputEncapsulation.setName(RunOptionEnum.outputEncapsulation);
//		outputEncapsulation.setValue(OutputEncapsulationEnum.none);
//		runOptions[2] = outputEncapsulation;
//
//		AsynchOptionInt primaryWait = new AsynchOptionInt();
//		primaryWait.setName(AsynchOptionEnum.primaryWaitThreshold);
//		primaryWait.setValue(0);
//		runOptions[3] = primaryWait;
//
//		AsynchOptionInt secondaryWait = new AsynchOptionInt();
//		secondaryWait.setName(AsynchOptionEnum.secondaryWaitThreshold);
//		secondaryWait.setValue(0);
//		runOptions[4] = secondaryWait;
//
//		// Now, run the report.
//		try
//		{
//			System.out.println("Running the report...");
////			System.out.println("Report search path is:");
////			System.out.println(reportPath);
//
////			AsynchReply res =
////                repService.run(new SearchPathSingleObject(reportPath), parameters, runOptions);
//
//            ReportServiceSpecification metadataSpec = new ReportServiceReportSpecification();
//            metadataSpec.setValue(new Specification(reportSpecString()));
//
//            AsynchReply res =
//                    repService.runSpecification(metadataSpec, parameters, runOptions);
//
//			System.out.println("... done.");
//
//			// The report is finished, let's fetch the results and save them to
//			// a file.
//			if (res.getStatus() == AsynchReplyStatusEnum.complete)
//
//			{
//				AsynchDetailReportOutput reportOutput = null;
//
//				for (int i = 0; i < res.getDetails().length; i++)
//				{
//					if (res.getDetails()[i]
//						instanceof AsynchDetailReportOutput)
//					{
//						reportOutput =
//							(AsynchDetailReportOutput)res.getDetails()[i];
//						break;
//					}
//				}
//
//				String[] data = reportOutput.getOutputPages();
//
//				System.out.println(
//					"Writing report output to " + outputPath + "...");
//				FileOutputStream fs = new FileOutputStream(outputPath);
//
//				// URIs in the output are relative on the server; we need to
//				// make them absolute so they reference the server properly.
////				String uriFix =
////					"http://" + serverHost + ":" + serverPort + "/ibmcognos/";
//
//				String uriFix =
//						"http://" + serverHost + "/ibmcognos/";
//
//				for (int idx = 0; idx < data.length; idx++)
//				{
//					String fixed_hunk =
//						replaceSubstring(data[idx], "../", uriFix);
//					fs.write(fixed_hunk.getBytes());
//				}
//
//				fs.close();
//				System.out.println("... done.");
//			}
//		}
//		catch (AxisFault ex)
//		{
//			String ex_str = CognosBIException.convertToString(ex);
//			System.out.println("SOAP exception!");
//			System.out.println(ex_str);
//		}
//		catch (Exception ex)
//		{
//			System.out.println("Unhandled exception!");
//			System.out.println("Message: " + ex.getMessage());
//			System.out.println("Stack trace:");
//			ex.printStackTrace();
//		}
//	}
//
//    private static String reportSpecString() {
//        return "<report xmlns=\"http://developer.cognos.com/schemas/report/12.0/\" useStyleVersion=\"10\" expressionLocale=\"en-us\">" +
//                "<modelPath>/content/folder[@name='Samples']/folder[@name='Models']/package[@name='GO Sales (analysis)']/model[@name='model']</modelPath>" +
//                "<drillBehavior/>" +
//                "<queries>" +
//                "<query name=\"Query1\">" +
//                "<source>" +
//                "<model/>" +
//                "</source>" +
//                "<selection><dataItemMeasure name=\"Quantity\"><dmMember><MUN>[Sales (analysis)].[Sales].[Quantity]</MUN><itemCaption>Quantity</itemCaption></dmMember><dmDimension><DUN>[Sales (analysis)].[Sales]</DUN><itemCaption>Sales</itemCaption></dmDimension><XMLAttributes><XMLAttribute output=\"no\" name=\"RS_dataType\" value=\"1\"/></XMLAttributes></dataItemMeasure><dataItemMeasure name=\"Unit price\"><dmMember><MUN>[Sales (analysis)].[Sales].[Unit price]</MUN><itemCaption>Unit price</itemCaption></dmMember><dmDimension><DUN>[Sales (analysis)].[Sales]</DUN><itemCaption>Sales</itemCaption></dmDimension><XMLAttributes><XMLAttribute output=\"no\" name=\"RS_dataType\" value=\"2\"/></XMLAttributes></dataItemMeasure></selection>" +
//                "</query>" +
//                "</queries>" +
//                "<layouts>" +
//                "<layout>" +
//                "<reportPages>" +
//                "<page name=\"Page1\"><style><defaultStyles><defaultStyle refStyle=\"pg\"/></defaultStyles></style>" +
//                "<pageBody><style><defaultStyles><defaultStyle refStyle=\"pb\"/></defaultStyles></style>" +
//                "<contents>" +
//                "<list refQuery=\"Query1\" horizontalPagination=\"true\" name=\"List1\">" +
//                "" +
//                "" +
//                "" +
//                "<noDataHandler>" +
//                "<contents>" +
//                "<block>" +
//                "<contents>" +
//                "<textItem>" +
//                "<dataSource>" +
//                "<staticValue>No Data Available</staticValue>" +
//                "</dataSource>" +
//                "<style>" +
//                "<CSS value=\"padding:10px 18px;\"/>" +
//                "</style>" +
//                "</textItem>" +
//                "</contents>" +
//                "</block>" +
//                "</contents>" +
//                "</noDataHandler>" +
//                "<style>" +
//                "<defaultStyles>" +
//                "<defaultStyle refStyle=\"ls\"/>" +
//                "</defaultStyles>" +
//                "<CSS value=\"border-collapse:collapse\"/>" +
//                "</style>" +
//                "<listColumns><listColumn><listColumnTitle><style><defaultStyles><defaultStyle refStyle=\"lt\"/></defaultStyles></style><contents><textItem><dataSource><dataItemLabel refDataItem=\"Quantity\"/></dataSource></textItem></contents></listColumnTitle><listColumnBody><style><defaultStyles><defaultStyle refStyle=\"lm\"/></defaultStyles></style><contents><textItem><dataSource><dataItemValue refDataItem=\"Quantity\"/></dataSource></textItem></contents></listColumnBody></listColumn><listColumn><listColumnTitle><style><defaultStyles><defaultStyle refStyle=\"lt\"/></defaultStyles></style><contents><textItem><dataSource><dataItemLabel refDataItem=\"Unit price\"/></dataSource></textItem></contents></listColumnTitle><listColumnBody><style><defaultStyles><defaultStyle refStyle=\"lm\"/></defaultStyles></style><contents><textItem><dataSource><dataItemValue refDataItem=\"Unit price\"/></dataSource></textItem></contents></listColumnBody></listColumn></listColumns></list>" +
//                "</contents>" +
//                "</pageBody>" +
//                "<pageHeader>" +
//                "<contents>" +
//                "<block><style><defaultStyles><defaultStyle refStyle=\"ta\"/></defaultStyles></style>" +
//                "<contents>" +
//                "<textItem><style><defaultStyles><defaultStyle refStyle=\"tt\"/></defaultStyles></style>" +
//                "<dataSource>" +
//                "<staticValue/>" +
//                "</dataSource>" +
//                "</textItem>" +
//                "</contents>" +
//                "</block>" +
//                "</contents>" +
//                "<style>" +
//                "<defaultStyles>" +
//                "<defaultStyle refStyle=\"ph\"/>" +
//                "</defaultStyles>" +
//                "<CSS value=\"padding-bottom:10px\"/>" +
//                "</style>" +
//                "</pageHeader>" +
//                "<pageFooter>" +
//                "<contents>" +
//                "<table>" +
//                "<tableRows>" +
//                "<tableRow>" +
//                "<tableCells>" +
//                "<tableCell>" +
//                "<contents>" +
//                "<date>" +
//                "<style>" +
//                "<dataFormat>" +
//                "<dateFormat/>" +
//                "</dataFormat>" +
//                "</style>" +
//                "</date>" +
//                "</contents>" +
//                "<style>" +
//                "<CSS value=\"vertical-align:top;text-align:left;width:25%\"/>" +
//                "</style>" +
//                "</tableCell>" +
//                "<tableCell>" +
//                "<contents>" +
//                "<pageNumber/>" +
//                "</contents>" +
//                "<style>" +
//                "<CSS value=\"vertical-align:top;text-align:center;width:50%\"/>" +
//                "</style>" +
//                "</tableCell>" +
//                "<tableCell>" +
//                "<contents>" +
//                "<time>" +
//                "<style>" +
//                "<dataFormat>" +
//                "<timeFormat/>" +
//                "</dataFormat>" +
//                "</style>" +
//                "</time>" +
//                "</contents>" +
//                "<style>" +
//                "<CSS value=\"vertical-align:top;text-align:right;width:25%\"/>" +
//                "</style>" +
//                "</tableCell>" +
//                "</tableCells>" +
//                "</tableRow>" +
//                "</tableRows>" +
//                "<style>" +
//                "<defaultStyles>" +
//                "<defaultStyle refStyle=\"tb\"/>" +
//                "</defaultStyles>" +
//                "<CSS value=\"border-collapse:collapse;width:100%\"/>" +
//                "</style>" +
//                "</table>" +
//                "</contents>" +
//                "<style>" +
//                "<defaultStyles>" +
//                "<defaultStyle refStyle=\"pf\"/>" +
//                "</defaultStyles>" +
//                "<CSS value=\"padding-top:10px\"/>" +
//                "</style>" +
//                "</pageFooter>" +
//                "</page>" +
//                "</reportPages>" +
//                "</layout>" +
//                "</layouts>" +
//                "<XMLAttributes><XMLAttribute output=\"no\" name=\"RS_CreateExtendedDataItems\" value=\"true\"/><XMLAttribute output=\"no\" name=\"listSeparator\" value=\",\"/><XMLAttribute output=\"no\" name=\"RS_modelModificationTime\" value=\"2013-01-08T15:29:50.333Z\"/></XMLAttributes></report>";
//    }
}
